package com.example.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.TimeUnit;

/**
 * @Description
 * @Author 26233
 * @Create 2021-10-28 17:50:54
 */

public class AioSocketServer {

    String hostName = "192.168.101.8";
    int port = 8888;
    AsynchronousServerSocketChannel asynchronousServerSocketChannel;
    public void init(){
        try {
            asynchronousServerSocketChannel = AsynchronousServerSocketChannel.open();
            asynchronousServerSocketChannel.bind(new InetSocketAddress(hostName, port));
            MyAttachment myAttachment = new MyAttachment();
            myAttachment.setAsynchronousServerSocketChannel(asynchronousServerSocketChannel);
            asynchronousServerSocketChannel.accept(myAttachment, new MyCompletionHandler());
            System.out.println("echo start");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {

        new AioSocketServer().init();

        try {
            TimeUnit.HOURS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}

class MyAttachment {
    AsynchronousServerSocketChannel asynchronousServerSocketChannel;
    AsynchronousSocketChannel client;
    ByteBuffer recv = ByteBuffer.allocate(1024);

    public AsynchronousSocketChannel getClient() {
        return client;
    }

    public void setClient(AsynchronousSocketChannel client) {
        this.client = client;
    }

    public AsynchronousServerSocketChannel getAsynchronousServerSocketChannel() {
        return asynchronousServerSocketChannel;
    }

    public void setAsynchronousServerSocketChannel(AsynchronousServerSocketChannel asynchronousServerSocketChannel) {
        this.asynchronousServerSocketChannel = asynchronousServerSocketChannel;
    }

    public ByteBuffer getRecv() {
        return recv;
    }

    public void setRecv(ByteBuffer recv) {
        this.recv = recv;
    }
}

class MyCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, MyAttachment> {

    @Override
    public void completed(AsynchronousSocketChannel client, MyAttachment attachment) {

        // 继续处理新的连接
        attachment.getAsynchronousServerSocketChannel().accept(attachment, this);

        // 传递连接
        MyAttachment myAttachment = new MyAttachment();
        myAttachment.setClient(client);

        // 读取数据
        client.read(myAttachment.getRecv(), myAttachment, new MyChannelHandler());
    }

    @Override
    public void failed(Throwable exc, MyAttachment attachment) {

    }
}

// 读取到数据后的处理
class MyChannelHandler implements CompletionHandler<Integer, MyAttachment> {
    @Override
    public void completed(Integer result, MyAttachment attachment) {

        AsynchronousSocketChannel client = attachment.getClient();
        // 收到的数据
        ByteBuffer recv = attachment.getRecv();

        System.out.println("recv len = " + recv.position());

    }

    @Override
    public void failed(Throwable exc, MyAttachment attachment) {

    }
}
